package com.mes.cloud.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: 记录修改前后的值 （在字段加 @PropertyMsg）
 * @author: syn
 * @create: 2019-11-04
 **/
public class UpdateFrontAfterUtil<T> {

    public String contrastObj(Object oldBean, Object newBean) {
        // 创建字符串拼接对象
        StringBuilder str = new StringBuilder();
        // 转换为传入的泛型T
        T pojo1 = (T) oldBean;
        T pojo2 = (T) newBean;
        // 通过反射获取类的Class对象
        Class clazz = pojo1.getClass();
        // 获取类型及字段属性
        Field[] fields = clazz.getDeclaredFields();
        return jdk8Before(fields, pojo1, pojo2, str,clazz);
//        return jdk8OrAfter(fields, pojo1, pojo2, str,clazz);
    }

    public Map<String ,String> contrastObj1(T oldBean, T newBean) {
        int i = 1;
        Map<String,String> resultMap = new HashMap<>();
        try {
            Class clazz = oldBean.getClass();
            Field[] fields = oldBean.getClass().getDeclaredFields();
            for (Field field : fields) {
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                Method getMethod = pd.getReadMethod();
                Object o1 = getMethod.invoke(oldBean);
                Object o2 = getMethod.invoke(newBean);
                if(o1==null || o2 == null){
                    continue;
                }
                if (!o1.toString().equals(o2.toString())) {
                    resultMap.put(field.getAnnotation(PropertyMsg.class).value(),"变更前:"+o1.toString()+" 变更后:"+o2.toString());
                    i++;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultMap;
    }

    // jdk8 普通循环方式
    public String jdk8Before(Field[] fields,T pojo1,T pojo2,StringBuilder str,Class clazz){
        int i = 1;
        try {
            for (Field field : fields) {
                if(field.isAnnotationPresent(PropertyMsg.class)){
                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                    // 获取对应属性值
                    Method getMethod = pd.getReadMethod();
                    Object o1 = getMethod.invoke(pojo1);
                    Object o2 = getMethod.invoke(pojo2);
                    if (o1 == null || o2 == null) {
                        continue;
                    }
                    if (!o1.toString().equals(o2.toString())) {
                        str.append(i + "、" + field.getAnnotation(PropertyMsg.class).value() + ":" + "修改前=>" + o1 + ",修改后=>" + o2 + "\n");
                        i++;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str.toString();
    }

    // lambda表达式，表达式内部的变量都是final修饰，需要传入需要传入final类型的数组
    public String jdk8OrAfter(Field[] fields, T pojo1, T pojo2, StringBuilder str, Class clazz){
        final int[] i = {1};
        Arrays.asList(fields).forEach(f -> {
            if(f.isAnnotationPresent(PropertyMsg.class)){
                try {
                    PropertyDescriptor pd = new PropertyDescriptor(f.getName(), clazz);
                    // 获取对应属性值
                    Method getMethod = pd.getReadMethod();
                    Object o1 = getMethod.invoke(pojo1);
                    Object o2 = getMethod.invoke(pojo2);
                    if (o1 == null || o2 == null) {
                        return;
                    }
                    if (!o1.toString().equals(o2.toString())) {
                        str.append(i[0] + "、" + f.getAnnotation(PropertyMsg.class).value() + ":" + "修改前=>" + o1 + "\t修改后=>" + o2 + "\n");
                        i[0]++;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
        return str.toString();
    }




//    public static void main(String[] args) {
//        TestChange u1 = new TestChange("我是谁", "ok", 30, "刘德华");
//        TestChange u2 = new TestChange("我在哪", "no", 20, "刘德");
//        UpdateFrontAfterUtil<TestChange> t = new UpdateFrontAfterUtil<>();
//        String str = t.contrastObj(u1, u2);
//        Map<String, String> map = t.contrastObj1(u1, u2);
//        if (str.equals("")) {
//            System.out.println("未有改变");
//        } else {
//            System.out.println(str);
//        }
//        if (map.equals("")) {
//            System.out.println("未有改变");
//        } else {
//            System.out.println(map);
//        }
//    }
//
//    public TestChange() {
//    }
//
//    public TestChange(String about, String lock, Integer age, String name) {
//        this.about = about;
//        this.lock = lock;
//        this.age = age;
//        this.name = name;
//    }
//
//    @PropertyMsg("关于")
//    private String about;
//
//    @PropertyMsg("a")
//    private String lock;
//
//    @PropertyMsg("年龄")
//    private Integer age;
//
//    @PropertyMsg("姓名")
//    private String name;
}
